from typing import Optional, List

from langchain_core.runnables import RunnableConfig
from pydantic import BaseModel, Field
from ...graph.nodes.base import BaseNodes, tool_node
from ...models.graph import GraphState


class LaunchContainerSchema(BaseModel):
    environment_type: str = Field(
        description="The type of environment to launch (e.g., 'docker', 'sandbox')"
    )
    image_name: str = Field(
        description="The name of the image to use for the environment"
    )
    template: str = Field(
        default=None,
        description="the project's template"
    )
    requires_approval: bool = Field(
        default=True,
        description="Whether this operation requires explicit user approval"
    )


class RunProjectSchema(BaseModel):
    command: str = Field(
        description="The command to run within the project environment"
    )
    working_directory: Optional[str] = Field(
        default=None,
        description="Optional working directory where the command should be executed"
    )
    requires_approval: bool = Field(
        default=False,
        description="Whether this operation requires explicit user approval"
    )


class ExecuteContainerCommandSchema(BaseModel):
    command: str = Field(
        description="The command to execute inside the container"
    )
    requires_approval: bool = Field(
        default=False,
        description="Whether this operation requires explicit user approval"
    )


class ProjectNodes(BaseNodes):
    @tool_node(args_schema=LaunchContainerSchema)
    def launch_container(self, state: GraphState, *, config: Optional[RunnableConfig] = None):
        """
        启动项目容器环境。创建项目构建、测试、运行所需的容器化环境。
        参数:
        - environment_type: (必填) 环境类型(如docker)
        - image_name: (必填) 容器镜像名称(如node:18, python:3.9)
        - template: (可选) 项目模板名称，需从支持列表中选择，不匹配则设为null
        - requires_approval: (可选) 是否需要用户批准，默认true
        用法:
        <launch_container>
        <environment_type>docker</environment_type>
        <image_name>python:3.9-slim</image_name>
        <template>Flask</template>
        </launch_container>
        """
        return self.wait_human_feedback()

    @tool_node(args_schema=ExecuteContainerCommandSchema)
    def execute_container_command(self, state: GraphState, *, config: Optional[RunnableConfig] = None):
        """
        容器内执行命令。在容器环境中安装依赖、配置环境或运行系统命令。
        参数:
        - command: (必填) 容器内执行的命令
        - requires_approval: (可选) 是否需要用户批准，高风险操作设为true，默认false
        用法:
        <execute_container_command>
        <command>npm install express</command>
        <requires_approval>true</requires_approval>
        </execute_container_command>
        """
        return self.wait_human_feedback()


    @tool_node(args_schema=RunProjectSchema)
    def run_project(self, state: GraphState, *, config: Optional[RunnableConfig] = None):
        """
        运行项目命令。在已启动的容器环境中执行项目相关命令。
        参数:
        - command: (必填) 项目运行命令
        - working_directory: (可选) 工作目录
        - requires_approval: (可选) 是否需要用户批准，默认false
        - is_gui: (可选) 是否为GUI应用，默认false
        用法:
        <run_project>
        <command>npm run dev</command>
        <requires_approval>false</requires_approval>
        <is_gui>true</is_gui>
        </run_project>
        """
        return self.wait_human_feedback()
